<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="python编写小型数据库二、结构设计  库模块 表模块 字段模块 引擎模块 条件模块 解析模块 交互模块 异常处理模块   以这些模块为基础，并且它的整体是作为一个 Python三方库存在，所以按每一个模块一个包来分，结构如下 syldb #这个库的名字,导入时语句为:import syldb _init__-py #模块主体,作为调度其他模块的入口，也就是引擎模块 _main_.py #直接调">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="https://goofyer.gitee.io/notes-on-computer-expertise/2022/02/23/python/python%E7%BC%96%E5%86%99%E5%B0%8F%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="python编写小型数据库二、结构设计  库模块 表模块 字段模块 引擎模块 条件模块 解析模块 交互模块 异常处理模块   以这些模块为基础，并且它的整体是作为一个 Python三方库存在，所以按每一个模块一个包来分，结构如下 syldb #这个库的名字,导入时语句为:import syldb _init__-py #模块主体,作为调度其他模块的入口，也就是引擎模块 _main_.py #直接调">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2022-02-23T11:02:52.989Z">
<meta property="article:modified_time" content="2022-03-06T12:01:01.452Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/notes-on-computer-expertise/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/notes-on-computer-expertise/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/notes-on-computer-expertise/css/style.css">

  
    
<link rel="stylesheet" href="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/notes-on-computer-expertise/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/">Home</a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/notes-on-computer-expertise/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://goofyer.gitee.io/notes-on-computer-expertise"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main"><article id="post-python/python编写小型数据库" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2022/02/23/python/python%E7%BC%96%E5%86%99%E5%B0%8F%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93/" class="article-date">
  <time class="dt-published" datetime="2022-02-23T11:02:52.989Z" itemprop="datePublished">2022-02-23</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h1 id="python编写小型数据库"><a href="#python编写小型数据库" class="headerlink" title="python编写小型数据库"></a>python编写小型数据库</h1><h2 id="二、结构设计"><a href="#二、结构设计" class="headerlink" title="二、结构设计"></a>二、结构设计</h2><ul>
<li><ul>
<li>库模块</li>
<li>表模块</li>
<li>字段模块</li>
<li>引擎模块</li>
<li>条件模块</li>
<li>解析模块</li>
<li>交互模块</li>
<li>异常处理模块</li>
</ul>
</li>
<li>以这些模块为基础，并且它的整体是作为一个 Python三方库存在，所以按每一个模块一个包来分，结构如下<ul>
<li>syldb #这个库的名字,导入时语句为:import syldb<ul>
<li>_init__-py #模块主体,作为调度其他模块的入口，也就是引擎模块</li>
<li>_main_.py #直接调用模块时的入口，也就是当执行 python3 -m syldb时执行的文件</li>
<li>case #条件判断模块<ul>
<li>_init_-py</li>
</ul>
</li>
<li>core#核心模块-<ul>
<li>_init_-py #核心模块主体</li>
<li>database.py#数据库模块</li>
<li>field.py #数据库字段模块</li>
<li>table.py #数据表模块</li>
</ul>
</li>
<li>exceptions #异常处理模块<ul>
<li>_init__-py</li>
</ul>
</li>
<li>parser # SQL 语法解析模块<ul>
<li>_init__.Py<h2 id="三、项目创建"><a href="#三、项目创建" class="headerlink" title="三、项目创建"></a>三、项目创建</h2></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>下面是创建项目的脚本，复制粘贴到/home/ shiyanlou/Code目录下的 gen.py 文件中运行就可以创建好上面定义出来的目录结构<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># !/ usr/bin/env python3#encoding: utf-8</span></span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="comment">#在当前目录下创建</span></span><br><span class="line">root_path = os.getcwd()</span><br><span class="line"><span class="comment">#目录列表</span></span><br><span class="line"><span class="comment">#子文件</span></span><br><span class="line">children = <span class="string">&#x27;&#123;&quot;name&quot;:&quot;%s.py&quot;,&quot;children&quot;:[],&quot;type&quot;: &quot;file&quot;&#125;&#x27;</span></span><br><span class="line"><span class="comment">#目录结构</span></span><br><span class="line">dir_map=[&#123;</span><br><span class="line">    <span class="comment"># name为模块的名字:建议用 syldb命名，方便后续的实验与课程同步</span></span><br><span class="line">    <span class="string">&quot;name&quot;</span> : <span class="string">&quot;syldb&quot;</span>,</span><br><span class="line">    <span class="string">&quot;type&quot;</span> : <span class="string">&quot;dir&quot;</span>,</span><br><span class="line">    <span class="string">&quot;children&quot;</span>:[</span><br><span class="line">        json.loads(children % <span class="string">&#x27;__init__&#x27;</span>),</span><br><span class="line">        json.loads(children % <span class="string">&#x27;__main__&#x27;</span>),</span><br><span class="line">        &#123;</span><br><span class="line">        <span class="string">&quot;name&quot;</span> : <span class="string">&quot;case&quot;</span>,</span><br><span class="line">        <span class="string">&quot;type&quot;</span> : <span class="string">&quot;dir&quot;</span>,</span><br><span class="line">        <span class="string">&quot;children&quot;</span> : [json.loads(children % <span class="string">&#x27;__init__&#x27;</span>)]</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">        <span class="string">&quot;name&quot;</span> : <span class="string">&quot;parse&quot;</span>,</span><br><span class="line">        <span class="string">&quot;type&quot;</span> :<span class="string">&quot;dir&quot;</span>,</span><br><span class="line">        <span class="string">&quot;children&quot;</span>: [json.loads(children % <span class="string">&#x27;__init__&#x27;</span>)]</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">        <span class="string">&quot;name&quot;</span> : <span class="string">&quot;exceptions&quot;</span>,</span><br><span class="line">        <span class="string">&quot;type&quot;</span> : <span class="string">&quot;dir&quot;</span>,</span><br><span class="line">        <span class="string">&quot;children&quot;</span>: [json.loads(children % <span class="string">&quot;__init__&quot;</span>)]</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">        <span class="string">&quot;name&quot;</span> : <span class="string">&quot;core&quot;</span>,</span><br><span class="line">        <span class="string">&quot;type&quot;</span> : <span class="string">&quot;dir&quot;</span>,</span><br><span class="line">        <span class="string">&quot;children&quot;</span>: [</span><br><span class="line">            json.loads(children % <span class="string">&quot;__init__&quot;</span>),</span><br><span class="line">            json.loads(children % <span class="string">&quot;database&quot;</span>),</span><br><span class="line">            json.loads(children % <span class="string">&quot;table&quot;</span>),</span><br><span class="line">            json.loads(children % <span class="string">&quot;field&quot;</span>)]</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;]</span><br><span class="line"><span class="comment">#创建文件夹或者文件</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">create</span>(<span class="params">path,kind</span>):</span></span><br><span class="line">    <span class="keyword">if</span> kind == <span class="string">&quot;dir&quot;</span>:</span><br><span class="line">        os.mkdir(path)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">open</span>(path, <span class="string">&quot;w&quot;</span>).close()</span><br><span class="line"><span class="comment">#递归创建目录</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">gen_project</span>(<span class="params">parent_path,map_obj</span>):</span></span><br><span class="line">    <span class="keyword">for</span> line <span class="keyword">in</span> map_obj:</span><br><span class="line">        path = os.path.join(parent_path,line[<span class="string">&quot;name&quot;</span>])</span><br><span class="line">        create(path,line[<span class="string">&#x27;type&#x27;</span>])</span><br><span class="line">        <span class="keyword">if</span> line[<span class="string">&#x27;children&#x27;</span>]:</span><br><span class="line">            gen_project(path,line[<span class="string">&quot;children&quot;</span>])</span><br><span class="line">    <span class="comment">#脚本入口</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span>():</span></span><br><span class="line">    gen_project(root_path, dir_map)</span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span> :</span><br><span class="line">    main()</span><br></pre></td></tr></table></figure>
<h1 id="数据字段模块的实现"><a href="#数据字段模块的实现" class="headerlink" title="数据字段模块的实现"></a>数据字段模块的实现</h1><h2 id="一、实验说明"><a href="#一、实验说明" class="headerlink" title="一、实验说明"></a>一、实验说明</h2><h3 id="1-1内容"><a href="#1-1内容" class="headerlink" title="1.1内容"></a>1.1内容</h3></li>
<li>本节开始进行数据库核心模块之一的数据库字段模块的实现。<h3 id="1-2涉及知识点"><a href="#1-2涉及知识点" class="headerlink" title="1.2涉及知识点"></a>1.2涉及知识点</h3></li>
<li>序列化</li>
<li>反序列化</li>
<li>Json<h3 id="1-3实验环境"><a href="#1-3实验环境" class="headerlink" title="1.3实验环境"></a>1.3实验环境</h3></li>
<li>Python3</li>
<li>xfce终端<h2 id="二、模块功能分析"><a href="#二、模块功能分析" class="headerlink" title="二、模块功能分析"></a>二、模块功能分析</h2></li>
<li>这个模块是数据库核心模块之一，所以定义在核心模块目录 core目录下的field.py 中，由于它是数据结构的最底层，所以选择从它开始设计实现。</li>
<li>它需要实现的有数据类型定义，数据类型约束，而且为了数据库的保存和加载，这里引入了序列化和反序列化的概念，然后根据我们之前的数据结构模型可以看到它是一个键值对方式存在，值应该是一个List列表，并且作为实际存放数据的结构体，它还需要支持数据操作，也就是基础的增、删、改、查操作，总结之后它具备的必备功能大致如下<ul>
<li>一个存放值的List列表</li>
<li>可定义数据类型</li>
<li>可定义数据约束</li>
<li>支持序列化和反序列化</li>
<li>支持增、删、改、查基础操作<h2 id="三、序列化和反序列化"><a href="#三、序列化和反序列化" class="headerlink" title="三、序列化和反序列化"></a>三、序列化和反序列化</h2><h3 id="3-1概念"><a href="#3-1概念" class="headerlink" title="3.1概念"></a>3.1概念</h3></li>
</ul>
</li>
<li>序列化其实就是把一个对象的结果转换成一段具有一定格式的数据，使它可以从内存中取出来并保存下来，并且可以通过反序列化把这段数据重新还原成一个原先的对象，保持状态属性的一致。比如我们这里要实现的数据字段模块，它是一个Field对象，拥有的属性包括值，数据类型，数据约束和基础操作，那么序列化就是把这个对象当前拥有的这些属性值保存下来，然后下次使用的时候解析加载这些值还原成这个对象，拥有原先的值，数据类型，数据约束和基础操作<h3 id="3-2定义序列化和反序列化接口"><a href="#3-2定义序列化和反序列化接口" class="headerlink" title="3.2定义序列化和反序列化接口"></a>3.2定义序列化和反序列化接口</h3></li>
<li>因为我们要保存的是整个数据结构，所有核心模块都需要实现序列化和反序列化，所以可以预定义一个接口规范，定义在核心模块目录core下的<strong>init</strong>.py中，代码如下<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="comment">#数据库核心模块序列化接口</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">serializedInterface</span>:</span></span><br><span class="line">    json = json <span class="comment">#内部定义一个json 对象,方便后续操作不需要import</span></span><br><span class="line">    <span class="comment">#反序列化方法</span></span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">deserialized</span>(<span class="params">obj</span>):</span></span><br><span class="line">        <span class="keyword">raise</span> NotImplementedError<span class="comment">#抛出未实现异常</span></span><br><span class="line">    <span class="comment">#序列化方法</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">serialized</span>(<span class="params">self</span>) :</span></span><br><span class="line">        <span class="keyword">raise</span> NotImplementedError<span class="comment">#抛出未实现异常</span></span><br></pre></td></tr></table></figure>
<h2 id="四、定义数据类型"><a href="#四、定义数据类型" class="headerlink" title="四、定义数据类型"></a>四、定义数据类型</h2></li>
<li>对于数据类型，这里只实现最基础的数据类型定义，后续如果有需要同学们可以自行扩展，用一个枚举类来进行定义，至于为什么要枚举类，后面在实现序列化和反序列化时就能知道了，这里先不解释，定义追加在核心模块目录core下的<strong>init</strong>-py中，代码如下<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> enum <span class="keyword">import</span> Enum</span><br><span class="line"><span class="comment">#字段类型枚举</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">FieldType</span>(<span class="params">Enum</span>) :</span></span><br><span class="line">    <span class="comment">#整型</span></span><br><span class="line">    INT = <span class="built_in">int</span> = <span class="string">&quot;int&quot;</span></span><br><span class="line">    <span class="comment">#字符型</span></span><br><span class="line">    VARCHAR = varchar = <span class="string">&quot;str&quot;</span></span><br><span class="line">    <span class="comment">#浮点型</span></span><br><span class="line">    FLOAT = <span class="built_in">float</span> = <span class="string">&quot;float&quot;</span></span><br><span class="line"><span class="comment">#数据类型映射</span></span><br><span class="line">TYPE_MAP = &#123;</span><br><span class="line">    <span class="string">&quot;int&quot;</span> : <span class="built_in">int</span>,</span><br><span class="line">    <span class="string">&quot;float&quot;</span> : <span class="built_in">float</span>,</span><br><span class="line">    <span class="string">&quot;str&quot;</span> : <span class="built_in">str</span>,</span><br><span class="line">    <span class="string">&quot;INT&quot;</span>: <span class="built_in">int</span>,</span><br><span class="line">    <span class="string">&quot;FLOAT&quot;</span> : <span class="built_in">float</span>,</span><br><span class="line">    <span class="string">&quot;VARCHAR&quot;</span> : <span class="built_in">str</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="五、定义数据约束"><a href="#五、定义数据约束" class="headerlink" title="五、定义数据约束"></a>五、定义数据约束</h2></li>
<li>数据约束与数据类型类似，这里依旧是用一个枚举类来实现，定义在核心模块目录core下的.__init_.py 中，代码如下<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">#字段主键枚举</span><br><span class="line">class FieldKey (Enum) :</span><br><span class="line">    PRIMARY = &quot;PRIMARY KEY&quot;    #主键约束</span><br><span class="line">    INCREMENT = &quot;AUTO_INCREMENT&quot;    #自增约束</span><br><span class="line">    UNIQUE = &quot;UNIQUE&quot;    #唯一约束</span><br><span class="line">    NOT_NULL = &quot;NOT MULL&quot;    #非空约束</span><br><span class="line">    NULL = &quot;MULL&quot;    #可空约束,作为默认的约束使用</span><br></pre></td></tr></table></figure>
<h2 id="六、实现数据字段模块"><a href="#六、实现数据字段模块" class="headerlink" title="六、实现数据字段模块"></a>六、实现数据字段模块</h2></li>
<li>首先根据上面整理出的那些必备功能属性，定义出 Field类的模型，记得继承上面定义的序列化接口，定义在核心模块目录core下的field.py 中，代码如下:<ul>
<li>数据类型</li>
<li>数据约束</li>
<li>默认值</li>
<li>数据</li>
<li>数据长度</li>
</ul>
</li>
<li>上面的判断和异常抛出都是为了让数据类型和数据约束符合要求而定义的，接下来就来实现增、删、改、查这些基础操作，定义在Field类内部，代码如下</li>
<li>这里核心代码其实就四个，分别是get_data, add , delete,modify，从名字就能看出方法的作用，就不再赘述了，然后另外三个方法则只是类型检查而已。</li>
<li>除了基础操作的四个方法，还有一些需要暴露出来的属性，如rows,type和 keys 这些，依旧定义在Field类中</li>
<li>最后就是序列化和反序列化了，这里我的实现思路是先把对象属性转为一个Json字符串，然后反序列化从这串3son字符串中解析出数据，重新实例化为对象</li>
<li>反序列化方法：它的作用其实就是调用类的静态方法解析Json字符串，从中获取数据，然后再还原成一个对应的对象，反序列化方法首先是对‘Json字符串解析为一个dict，然后从中获取对应的键值进行对象初始化，再调用对象的add方法把数据绑定回去，最后返回这个对象、</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">#判断数据类型是否符合</span><br><span class="line">def __check_type(self, value):</span><br><span class="line">    #如果该值的类型不符合定义好的类型,抛出类型错误异常</span><br><span class="line">    if value is not None and not isinstance(value，TYPE_AAP[self.__type.value]):</span><br><span class="line">        raise TypeError(&#x27;data type error，value must be %s&#x27; % self._type)</span><br><span class="line">#判断指定位置数据是否存在</span><br><span class="line">def _check_index(self,index):</span><br><span class="line">    #如果指定位置不存在,抛出不存在该元素异常</span><br><span class="line">    if not isinstance(index，int) or not -index &lt; self._rows &gt; index:</span><br><span class="line">        raise Exception( &#x27;Not this element&quot;)</span><br><span class="line">    return True</span><br><span class="line">#键值约束</span><br><span class="line">def _check_keys(self, value):</span><br><span class="line">    #如果字段包含自增键,则选择合适的值自动自增</span><br><span class="line">    if FieldKey. INCREMENT in self.__keys:</span><br><span class="line">        #如果值为空,则用字段数据长度作为基值自增</span><br><span class="line">        if value is None:</span><br><span class="line">            value = self.__rows +1</span><br><span class="line">        #如果值已存在，则抛出一个值已经存在的异常</span><br><span class="line">        if value in self.__values:</span><br><span class="line">            raise Exception(&#x27;value %s exists&#x27;% value)</span><br><span class="line">    #如果字段包含主键约束或者唯一约束,判断值是否存在</span><br><span class="line">    if FieldKey.PRIMARY in self.__keys or FieldKey.UNIQUE in self._keys:</span><br><span class="line">        #如果值已存在，抛出存在异常</span><br><span class="line">        if value in self.__values:</span><br><span class="line">            raise Exception(&#x27;value %s exists&#x27;% value)</span><br><span class="line">    #如果该字段包含主键或者非空键，并且添加的值为空值，则抛出值不能为空异常</span><br><span class="line">    if (FieldKey.PRIMARY in self.__keys or FieldKey.NOT_NULL in self._keys) and value is None:</span><br><span class="line">        raise Exception(&quot;Field Not Null&quot;)</span><br><span class="line">    return value</span><br><span class="line">        #删除指定位置数据</span><br><span class="line">def delete(self， index):</span><br><span class="line">    #如果删除的位置不存在,抛出不存在该元素异常</span><br><span class="line">    self.__check_index(index)</span><br><span class="line">    #删除数据</span><br><span class="line">    self.__values.pop(index)</span><br><span class="line">    #教据长度减一</span><br><span class="line">    self.__rows -= 1</span><br><span class="line">    #修改指定位置数据</span><br><span class="line">def modify(self，index,value):</span><br><span class="line">    #如果修改的位置小于o或者大于数据总长度,抛出不存在该元素异常</span><br><span class="line">    self.__check_index( index)</span><br><span class="line">    #判断数据是否符合约束要求</span><br><span class="line">    value = self.__check_keys(value)</span><br><span class="line">    #如果修改的值类型不符合定义好的类型,抛出类型错误异常</span><br><span class="line">    self.__check_type(value)</span><br><span class="line">    #修改数据</span><br><span class="line">    self.__values[index] = value</span><br><span class="line">#获取字段数据约束</span><br><span class="line">def get_keys(self):</span><br><span class="line">    return self.__keys</span><br><span class="line">#获取字段类型</span><br><span class="line">def get_type(self):</span><br><span class="line">    return self.__type</span><br><span class="line">#获取数据长度</span><br><span class="line">def length(self):</span><br><span class="line">    return self.__rows</span><br><span class="line">#序列化对象</span><br><span class="line">def serialized(self):</span><br><span class="line">    return SerializedInterface.json.dumps(&#123;</span><br><span class="line">        &#x27;key&#x27; : [key.value for key in self._keys],</span><br><span class="line">        #数据约束</span><br><span class="line">        &#x27;type&#x27; : self.__type.value,</span><br><span class="line">        #数据类型</span><br><span class="line">        &#x27;values&#x27; : self.__values,</span><br><span class="line">        #数据</span><br><span class="line">        &#x27;default&#x27; : self.__default</span><br><span class="line">        #默认值</span><br><span class="line">    &#125;)</span><br><span class="line">#反序列化为对象</span><br><span class="line">@staticmethod</span><br><span class="line">def deserialized(data):</span><br><span class="line">    #将数据转化为Json 对象</span><br><span class="line">    json_data = SerializedInterface.json.loads(data)</span><br><span class="line">    #转换Json对象中key的值为枚举类FieldKey中的属性</span><br><span class="line">    keys = [FieldKey(key) for key in json_data[&#x27;key&#x27;]</span><br><span class="line">    #传入解析出来的数据类型和字段键并实例化一个 Field 对象</span><br><span class="line">    obj = Field(FieldType(json_data[&#x27;type&#x27;])，keys，default=json_data[ &#x27;default&#x27;])</span><br><span class="line">    #为Field 对象绑定数据</span><br><span class="line">    for value in json_data[&#x27;values&#x27;]:</span><br><span class="line">        obj.add(value)</span><br><span class="line">    #返回该 Field 对象</span><br><span class="line">    return obj</span><br><span class="line">    </span><br></pre></td></tr></table></figure>
<h1 id="数据表模块的实现"><a href="#数据表模块的实现" class="headerlink" title="数据表模块的实现"></a>数据表模块的实现</h1><h2 id="一、实验说明-1"><a href="#一、实验说明-1" class="headerlink" title="一、实验说明"></a>一、实验说明</h2><h3 id="1-1内容-1"><a href="#1-1内容-1" class="headerlink" title="1.1内容"></a>1.1内容</h3><ul>
<li>本节接着上一节实现的数据字段模块，实现在它之上的另一个同为核心模块之一的数据表模块。<h3 id="1-2实验环境"><a href="#1-2实验环境" class="headerlink" title="1.2实验环境"></a>1.2实验环境</h3></li>
<li>Python3<h2 id="二、模块功能分析-1"><a href="#二、模块功能分析-1" class="headerlink" title="二、模块功能分析"></a>二、模块功能分析</h2></li>
<li>这个模块在数据字段摸块之上，也就是数据结构模型中的表，它会包含字段对象Field 构成一张数据表，而且从字段模块可以知道它自身是没有名字的，加上数据结构模型中我们是设计为键值对来存放，所以它需要有一个属性来存放这些健值对，键就是字段名，值就是Field对象，然后数据表的执行动作依旧是增、删、改、查，只不过它会比较复杂，因为操作多了条件判断，这一节条件判断会先搁置，等到后续章节实现条件判断模块那一节中才会回过头来实现。再者就是序列化和反序列化了，总结下来它需要的数据和功能如下<ul>
<li>一个存放Field对象的键值对字典</li>
<li>添加字段操作</li>
<li>支持增、删、改、查操作</li>
<li>序列化和反序列化<h2 id="三、实现数据表模块"><a href="#三、实现数据表模块" class="headerlink" title="三、实现数据表模块"></a>三、实现数据表模块</h2><h3 id="3-1对象的初始化"><a href="#3-1对象的初始化" class="headerlink" title="3.1对象的初始化"></a>3.1对象的初始化</h3></li>
</ul>
</li>
<li>依旧是先实现对象的初始化方法，先看代码再来具体分析，代码如下，定义在core目录下的 table.py文件中<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">from syldb.core import SerializedInterface</span><br><span class="line">from syldb.core.field import Field</span><br><span class="line">#数据表对象</span><br><span class="line">class Table(serializedInterface) :</span><br><span class="line">    def _init__(self,**options):</span><br><span class="line">        self.__field_names = []</span><br><span class="line">        #数据表所有字段名</span><br><span class="line">        self.__field_objs =&#123;&#125;</span><br><span class="line">        #数据表字段名与字段对象映射</span><br><span class="line">        self._rows = 0</span><br><span class="line">        #数据条目数</span><br><span class="line">        </span><br><span class="line">        #获取所有字段名和字段对象为数据表初始化字段</span><br><span class="line">        for field_name, field_obj in options.items():</span><br><span class="line">            #进行字段添加</span><br><span class="line">            self.add_field(field_name，field_obj)</span><br></pre></td></tr></table></figure>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2022/02/23/python/python%E7%BC%96%E5%86%99%E5%B0%8F%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93/" data-id="cl403sxrj0026f8vuazakfd6r" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/notes-on-computer-expertise/2022/02/27/%E7%82%89%E7%9F%B3%E4%BC%A0%E8%AF%B4/%E7%AC%AC%E4%B8%80%E6%AD%A5%E5%BC%80%E5%8F%91%E6%B8%B8%E6%88%8F%E9%80%89%E6%8B%A9%E7%95%8C%E9%9D%A2/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          (no title)
        
      </div>
    </a>
  
  
    <a href="/notes-on-computer-expertise/2022/02/21/Spring%E5%BC%80%E5%8F%91/%E7%BB%83%E4%B9%A0%E9%A2%98/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title"></div>
    </a>
  
</nav>

  
</article>


</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C#工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C++工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/Mysql/">Mysql</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/blender/">blender</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/linux/">linux</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/manim/">manim</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/spring/">spring</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/">vba基础操作</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E5%88%9B%E9%80%A0%E6%A8%A1%E5%BC%8F/">创造模式</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/">操作系统</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">操作系统基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91/">操作系统开发</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E5%AD%A6/">数学</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">数据结构基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%A8%A1%E6%9D%BF/">模板</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">深度学习</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%8B%B1%E8%AF%AD/">英语</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%99%9A%E5%B9%BB4/">虚幻4</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/">计算机组成原理</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/notes-on-computer-expertise/tags/C/" rel="tag">C++</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/notes-on-computer-expertise/tags/C/" style="font-size: 10px;">C++</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/05/">May 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/03/">March 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/02/">February 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/01/">January 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2021/12/">December 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/31/vue/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6%E9%AA%8C%E8%AF%81%E7%A0%81%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/26/%E6%95%B0%E6%8D%AE%E5%BA%93/navicat%E5%AE%89%E8%A3%85/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/25/%E8%99%9A%E5%B9%BB4%E5%BC%95%E6%93%8E%E5%BC%80%E5%8F%91/%E8%99%9A%E5%B9%BB%E5%9B%9B%20mod%E5%88%B6%E4%BD%9C/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/python/python%E6%89%B9%E9%87%8F%E7%94%9F%E6%88%90%E6%95%B0%E6%8D%AE/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C%E7%AC%94%E8%AE%B0/EXCEL%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/">(no title)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2022 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/notes-on-computer-expertise/" class="mobile-nav-link">Home</a>
  
    <a href="/notes-on-computer-expertise/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/notes-on-computer-expertise/js/jquery-3.4.1.min.js"></script>



  
<script src="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.js"></script>




<script src="/notes-on-computer-expertise/js/script.js"></script>





  </div>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</body>
</html>